﻿namespace ConsoleApplication
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Xml.Linq;
    using System.Xml.Serialization;

    using JMDict.ObjectModel;

    class Program
    {
        const string dictionnaryFileName = "JMdict_e.xml";

        static Dictionary DeSerializer(XElement element)
        {
            var serializer = new XmlSerializer(typeof(Dictionary));
            return (Dictionary)serializer.Deserialize(element.CreateReader());
        }

        private static bool GetCharsInRange(string text, int min, int max)
        {
            return text.Any(e => e >= min && e <= max);
        }

        static void Main(string[] args)
        {
            var sw = Stopwatch.StartNew();
            var dic = DeSerializer(XElement.Load(dictionnaryFileName));
            Console.WriteLine("Loading dictionary file took " + sw.ElapsedMilliseconds + "ms. Ready to search.");                  
            
            string searchKeyWord = string.Empty;
           

            while (true)
            {
                Console.Write("Input search keyword (q to quit): ");
                searchKeyWord = Console.ReadLine();

                if (searchKeyWord == "q" || searchKeyWord == "ｑ" )
                {
                    break;
                }
                             
                IEnumerable<Entry> selection;

                var romaji = GetCharsInRange(searchKeyWord, 0x0020, 0x007E);
                //var hiragana = GetCharsInRange(searchKeyWord, 0x3040, 0x309F);
                var katakana = GetCharsInRange(searchKeyWord, 0x30A0, 0x30FF);
                var kanji = GetCharsInRange(searchKeyWord, 0x4E00, 0x9FBF);

                if (kanji)
                {
                    selection = from e in dic.Entries
                                from k in e.Kanjis
                                where k.Reading.StartsWith(searchKeyWord)
                                select e;
                }
                else if (romaji)
                {
                    selection = from e in dic.Entries
                                from s in e.Senses
                                from g in s.gloss
                                from t in g.Text
                                where t.Contains(searchKeyWord)
                                select e;
                }
                else
                {
                    selection = from e in dic.Entries
                                from r in e.ReadingElements
                                where r.Reading.StartsWith(searchKeyWord)
                                select e;
                }

                DisplayEntries(selection);           
            }
        }

        public static void DisplayEntries(IEnumerable<Entry> selection)
        {
            var defaultColor = Console.ForegroundColor;

            foreach (var item in selection)
            {
                Console.ForegroundColor = ConsoleColor.Red;

                foreach (var kanji in item.Kanjis)
                {
                    Console.Write(kanji.Reading + "    ");
                }

                Console.ForegroundColor = ConsoleColor.Green;
               
                foreach (var re in item.ReadingElements)
                {
                    Console.Write(re.Reading + "    ");
                }

                Console.ForegroundColor = ConsoleColor.Yellow;
                foreach (var sense in item.Senses)
                {
                    foreach (var gloss in sense.gloss)
                    {
                        foreach (var text in gloss.Text)
                        {
                            Console.Write(text + ", ");
                        }
                    }
                }

                Console.WriteLine();
            }

            Console.ForegroundColor = defaultColor;
        }    
    }
}
